﻿Imports System.Math
Imports System.Drawing
Imports System.Windows.Forms
Imports System.IO

Public Class Form4

    Dim image1 As Bitmap
    Dim imageSize
    Private Buffer_Block(7, 7) As Byte
    Private quantization_matrix(7, 7) As Byte
    Private DCT_Block(7, 7) As Long
    Dim masterImageArray As New List(Of BlockChars)
    Dim savedFileName As String
    Private Const PI = 3.14159265358979

    Private Sub Form4_Load(sender As Object, e As System.EventArgs) Handles Me.Load

        quantization_matrix(0, 0) = 16
        quantization_matrix(1, 0) = 11
        quantization_matrix(2, 0) = 10
        quantization_matrix(3, 0) = 16
        quantization_matrix(4, 0) = 24
        quantization_matrix(5, 0) = 40
        quantization_matrix(6, 0) = 51
        quantization_matrix(7, 0) = 61
        quantization_matrix(0, 1) = 12
        quantization_matrix(1, 1) = 12
        quantization_matrix(2, 1) = 14
        quantization_matrix(3, 1) = 19
        quantization_matrix(4, 1) = 26
        quantization_matrix(5, 1) = 58
        quantization_matrix(6, 1) = 60
        quantization_matrix(7, 1) = 55
        quantization_matrix(0, 2) = 14
        quantization_matrix(1, 2) = 13
        quantization_matrix(2, 2) = 16
        quantization_matrix(3, 2) = 24
        quantization_matrix(4, 2) = 40
        quantization_matrix(5, 2) = 57
        quantization_matrix(6, 2) = 69
        quantization_matrix(7, 2) = 56
        quantization_matrix(0, 3) = 14
        quantization_matrix(1, 3) = 17
        quantization_matrix(2, 3) = 22
        quantization_matrix(3, 3) = 29
        quantization_matrix(4, 3) = 51
        quantization_matrix(5, 3) = 87
        quantization_matrix(6, 3) = 80
        quantization_matrix(7, 3) = 62
        quantization_matrix(0, 4) = 18
        quantization_matrix(1, 4) = 22
        quantization_matrix(2, 4) = 37
        quantization_matrix(3, 4) = 56
        quantization_matrix(4, 4) = 68
        quantization_matrix(5, 4) = 109
        quantization_matrix(6, 4) = 103
        quantization_matrix(7, 4) = 77
        quantization_matrix(0, 5) = 24
        quantization_matrix(1, 5) = 35
        quantization_matrix(2, 5) = 55
        quantization_matrix(3, 5) = 64
        quantization_matrix(4, 5) = 81
        quantization_matrix(5, 5) = 104
        quantization_matrix(6, 5) = 113
        quantization_matrix(7, 5) = 92
        quantization_matrix(0, 6) = 49
        quantization_matrix(1, 6) = 64
        quantization_matrix(2, 6) = 78
        quantization_matrix(3, 6) = 87
        quantization_matrix(4, 6) = 103
        quantization_matrix(5, 6) = 121
        quantization_matrix(6, 6) = 120
        quantization_matrix(7, 6) = 101
        quantization_matrix(0, 7) = 72
        quantization_matrix(1, 7) = 92
        quantization_matrix(2, 7) = 95
        quantization_matrix(3, 7) = 98
        quantization_matrix(4, 7) = 112
        quantization_matrix(5, 7) = 100
        quantization_matrix(6, 7) = 103
        quantization_matrix(7, 7) = 99

    End Sub

    Private Sub btnBrowseImage_Click(sender As System.Object, e As System.EventArgs) Handles btnBrowseImage.Click
        ofdLoadImage.Title = "Please Select a File"
        ofdLoadImage.InitialDirectory = "C:temp"
        ofdLoadImage.ShowDialog()
    End Sub

    Private Sub ofdLoadImage_FileOk(sender As System.Object, e As System.ComponentModel.CancelEventArgs) Handles ofdLoadImage.FileOk
        ofdLoadImage.OpenFile()
        tbImage.Text = ofdLoadImage.FileName.ToString()
        image1 = Image.FromFile(tbImage.Text)
    End Sub

    Sub CalculateDCT(imageToCalculate As Bitmap, imgArray As List(Of BlockChars))
        imageSize = imageToCalculate.Size
        Dim numberofBlocks = (imageSize.Width / 8) * (imageSize.Height / 8)
        Dim blockCounter As Integer = 1

        For j = 0 To (imageSize.height / 8) - 1
            For i = 0 To (imageSize.width / 8) - 1
                Dim xctr As Integer = 0
                For xx = 0 + (i * 8) To 7 + (i * 8)
                    Dim yctr As Integer = 0
                    For yy = 0 + (j * 8) To 7 + (j * 8)
                        Buffer_Block(xctr, yctr) = (0.299 * imageToCalculate.GetPixel(xx, yy).R) + (0.5815 * imageToCalculate.GetPixel(xx, yy).G) + (0.114 * imageToCalculate.GetPixel(xx, yy).B)
                        yctr += 1
                    Next
                    xctr += 1
                Next

                Dim Temp As Double = 0
                Dim U As Integer, V As Integer, X As Integer, Y As Integer = 0

                For U = 0 To 7
                    For V = 0 To 7
                        Temp = 0

                        For X = 0 To 7
                            For Y = 0 To 7
                                Temp = Temp + (Buffer_Block(X, Y)) * _
               Cos((((2 * X) + 1) * U * PI) / 16) * _
               Cos((((2 * Y) + 1) * V * PI) / 16)

                            Next Y
                        Next X

                        'DCT_Block(U, V) = Rnd((C(U) * C(V) * Temp / 4) / quantization_matrix(U, V))
                        DCT_Block(U, V) = (C(U) * C(V) * Temp / 4)
                    Next V
                Next U

                imgArray.Add(New BlockChars(blockCounter, Print_DCT(), j, i))
                blockCounter += 1
            Next
        Next
    End Sub

    Private Function Print_DCT() As Integer
        Dim I As Integer, J As Integer = 0
        Dim totalDCT As Integer = 0
        'For I = 0 To 3
        '    For J = 0 To 3
        '        If DCT_Block(J, I) <> 0 Then
        '            totalDCT += 1
        '        End If

        '    Next J
        'Next I
        'Return totalDCT


        For I = 0 To 3
            For J = 0 To 3
                If Not (J = 0 AndAlso I = 0) Then
                    totalDCT += If(DCT_Block(J, I) < 0, DCT_Block(J, I) * -1, DCT_Block(J, I))
                End If
            Next J
        Next I


        Return totalDCT / 15
    End Function

    Private Function C(Num As Integer) As Double
        If Num = 0 Then
            C = 1 / Math.Sqrt(2)
        Else
            C = 1
        End If
        Return C
    End Function

    Structure BlockChars
        Public blockNumber As Integer
        Public dctValue As Integer
        Public xValue As Integer
        Public yValue As Integer
        Public Sub New(blockNumber As Integer, dctValue As Integer, xValue As Integer, yValue As Integer)
            Me.blockNumber = blockNumber
            Me.xValue = xValue
            Me.yValue = yValue
            Me.dctValue = dctValue
        End Sub
    End Structure

    Private Sub btnScanImage_Click(sender As System.Object, e As System.EventArgs) Handles btnScanImage.Click
        CalculateDCT(image1, masterImageArray)
        processBlockDifferences()
    End Sub

    Sub processBlockDifferences()
        Dim tifimage As Image = Image.FromFile(tbImage.Text) 'indexed format image.
        Dim NonIndexedImage As New Bitmap(tifimage.Width, tifimage.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

        Dim g As Graphics = Graphics.FromImage(CType(NonIndexedImage, Image))

        g.DrawImage(tifimage, 0, 0, tifimage.Width, tifimage.Height)
        g.Dispose()
        tifimage.Dispose()


        Dim ctrBlock As Integer = masterImageArray.Count - 1
        For ctr = 0 To ctrBlock
            If masterImageArray(ctr).dctValue >= TextBoxDCTCtr.Text Then
                Dim processBlockNumber As Integer = masterImageArray(ctr).blockNumber
                Dim xValue As Integer = masterImageArray(ctr).yValue
                Dim yValue As Integer = masterImageArray(ctr).xValue

                Dim xLine As Integer = 0
                For xx = 0 + (xValue * 8) To 7 + (xValue * 8)
                    Dim yLine As Integer = 0
                    For yy = 0 + (yValue * 8) To 7 + (yValue * 8)
                        If (xLine = 0 OrElse xLine = 7) OrElse (yLine = 0 OrElse yLine = 7) Then
                            NonIndexedImage.SetPixel(xx, yy, Color.Red) ' Color.FromArgb(rc, gc, bc))                                    
                        End If
                        yLine += 1
                    Next
                    Me.PictureBox1.Image = NonIndexedImage
                    Me.PictureBox1.Refresh()
                    xLine += 1
                Next

            End If
        Next
        savedFileName = Path.GetDirectoryName(tbImage.Text) & "\xxx" & ofdLoadImage.SafeFileName
        NonIndexedImage.Save(savedFileName, System.Drawing.Imaging.ImageFormat.Jpeg)
    End Sub

    Private Sub btnReprocess_Click(sender As System.Object, e As System.EventArgs) Handles btnReprocess.Click
        processBlockDifferences()
    End Sub
End Class